/*-------------------------------------------------------------------------
 *
 * extensible.h
 *	  Definitions for extensible nodes and custom scans
 *
 *
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/nodes/ag_extensible.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef AG_EXTENSIBLE_H
#define AG_EXTENSIBLE_H


#include "nodes/execnodes.h"
#include "nodes/plannodes.h"
#include "nodes/relation.h"

/* maximum length of an extensible node identifier */
#define EXTNODENAME_MAX_LEN					64

/*
 * An extensible node is a new type of node defined by an extension.  The
 * type is always T_EXTENSIBLE_NODE, while the extnodename identifies the
 * specific type of node.  extnodename can be looked up to find the
 * ExtensibleNodeMethods for this node type.
 */
typedef struct ExtensibleNode {
    NodeTag		type;
    const char *extnodename;	/* identifier of ExtensibleNodeMethods */
} ExtensibleNode;

/*
 * node_size is the size of an extensible node of this type in bytes.
 *
 * nodeCopy is a function which performs a deep copy from oldnode to newnode.
 * It does not need to copy type or extnodename, which are copied by the
 * core system.
 *
 * nodeEqual is a function which performs a deep equality comparison between
 * a and b and returns true or false accordingly.  It does not need to compare
 * type or extnodename, which are compared by the core system.
 *
 * nodeOut is a serialization function for the node type.  It should use the
 * output conventions typical for outfuncs.c.  It does not need to output
 * type or extnodename; the core system handles those.
 *
 * nodeRead is a deserialization function for the node type.  It does not need
 * to read type or extnodename; the core system handles those.  It should fetch
 * the next token using pg_strtok() from the current input stream, and then
 * reconstruct the private fields according to the manner in readfuncs.c.
 *
 * All callbacks are mandatory.
 */
typedef struct ExtensibleNodeMethods {
    const char *extnodename;
    Size		node_size;
    void		(*nodeCopy) (struct ExtensibleNode *newnode,
                            const struct ExtensibleNode *oldnode);
    bool		(*nodeEqual) (const struct ExtensibleNode *a,
                             const struct ExtensibleNode *b);
    void		(*nodeOut) (struct StringInfoData *str,
                           const struct ExtensibleNode *node);
    void		(*nodeRead) (struct ExtensibleNode *node);
} ExtensibleNodeMethods;

extern void ag_extensiblecpp_register_ag_nodes();
extern void RegisterAGExtensibleNodeMethods(const ExtensibleNodeMethods *method);
extern const ExtensibleNodeMethods *GetExtensibleAGNodeMethods(const char *name,
                                                               bool missing_ok);


extern char* AgNodeToString(const void *obj);
extern void outNode_age(struct StringInfoData *str, const void *obj);
extern void outToken_age(struct StringInfoData *str, const char *s);

extern void* stringToAGNode(char* str);
extern void* nodeRead_AG(char* token, int tok_len);

#endif							/* AG_EXTENSIBLE_H */
